package com.company.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.company.base.GzhModel;
import com.company.pushTools.WXAccessToken;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;

/**
 * @author lcl
 * @Title: AuthUtil
 * @ProjectName smart-planet
 * @Description: GZH 与微信服务器接口交互
 * @date 2019/1/17上午11:01
 */
@Component
public class GzhUtils {
    public final static String ZZHAutoLogin = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=";
    public static final Logger LOGGER = LoggerFactory.getLogger(GzhUtils.class);
    @Autowired
    private RedisUtils R;

    /**
     * 获取access_token
     * 如果缓存有则直接从缓存区，如果没有则重新请求生成
     * @return
     */
    public String getAccessToken(String appId){
        String accessToken = (String) R.get(Constant.WEIXIN_GZH_TOKEN+appId);
        if (accessToken != null) {
            return accessToken;
        }

        AssertUtils.isNullOrEmpty(appId,"获取accessToken，phone不能为空");
        GzhModel gzhModel = R.get(Constant.GZH_Config+appId,GzhModel.class);
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" +
                "&appid="+gzhModel.getAppId()+
                "&secret="+gzhModel.getSecret();
        JSONObject jsonObject = HttpClientUtils.doGetJson(url);
        accessToken = (String) jsonObject.get("access_token");
        // 微信 access_token 返回的有效期 7200
        R.set(Constant.WEIXIN_GZH_TOKEN+appId, accessToken, 7000);
        return accessToken;
    }



    /**
     * 授权登录时获取微信accessToken
     * 网页授权接口调用凭证,注意：此access_token与基础支持的access_token不同
     * @return
     */
    public WXAccessToken getCurrentAccessTokenByCode(String appId,String code) {
        AssertUtils.isNullOrEmpty(appId,"登录，appId不能为空");
        AssertUtils.isNullOrEmpty(appId,"登录，code不能为空");
        GzhModel gzhModel = R.get(Constant.GZH_Config+appId,GzhModel.class);
        AssertUtils.isNullOrEmpty(appId,"登录，没有找到配置");

        String access_token_url = ZZHAutoLogin+appId+"&secret="+gzhModel.getSecret()+"&code="+code+"&grant_type=authorization_code";
        JSONObject accessTokenModel = HttpClientUtils.doGetJson(access_token_url);
        LOGGER.info("微信登录授权 ---- > 原始accessToken "+JSON.toJSONString(accessTokenModel));
        AssertUtils.isNull(accessTokenModel,"微信授权失败，请重试");
        WXAccessToken accessToken = new WXAccessToken();
        accessToken.setAccess_token(accessTokenModel.getString("access_token"));
        accessToken.setOpenid(accessTokenModel.getString("openid"));
        accessToken.setUnionid(accessTokenModel.getString("unionid"));
        accessToken.setExpires_in(accessTokenModel.getInteger("expires_in"));
        return accessToken;
    }



    /**
     * 获取服务号关注的人员列表
     * @return
     */
    public JSONObject getFollowList(String accessToken,String firstOpenId){
        String infoUrl="https://api.weixin.qq.com/cgi-bin/user/get?access_token=" +accessToken+
                "&openid=" +firstOpenId;
        JSONObject resultData = HttpClientUtils.doGetJson(infoUrl);
        return resultData;
    }


    /**
     * 创建永久二维码(字符串)
     * @param userId 用户id
     * @return
     */
    public static JSONObject createForeverStrTicket(String token,String userId) throws IOException {
        String url="https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + token;
        JSONObject jsonObject = new JSONObject();
        JSONObject scene = new JSONObject();
        JSONObject actionInfo = new JSONObject();
        scene.put("scene_str", userId);
        actionInfo.put("scene", scene);
        jsonObject.put("action_name", "QR_LIMIT_STR_SCENE");
        jsonObject.put("action_info", actionInfo);
        return HttpClientUtils.doPostJson(url,jsonObject);
    }


    /**
     * 上传本地文件到微信获取mediaId
     * @param filePath
     * @param accessToken
     * @param type
     * @return
     * @throws IOException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchProviderException
     * @throws KeyManagementException
     */
    public static String upload(String filePath, String accessToken,String type) throws IOException, NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException {
        File file = new File(filePath);
        if (!file.exists() || !file.isFile()) {
            throw new IOException("文件不存在");
        }
        String url = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN&type=TYPE";
        url  = url.replace("ACCESS_TOKEN", accessToken).replace("TYPE",type);

        URL urlObj = new URL(url);
        //连接
        HttpURLConnection con = (HttpURLConnection) urlObj.openConnection();

        con.setRequestMethod("POST");
        con.setDoInput(true);
        con.setDoOutput(true);
        con.setUseCaches(false);

        //设置请求头信息
        con.setRequestProperty("Connection", "Keep-Alive");
        con.setRequestProperty("Charset", "UTF-8");

        //设置边界
        String BOUNDARY = "----------" + System.currentTimeMillis();
        con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);

        StringBuilder sb = new StringBuilder();
        sb.append("--");
        sb.append(BOUNDARY);
        sb.append("\r\n");
        sb.append("Content-Disposition: form-data;name=\"file\";filename=\"" + file.getName() + "\"\r\n");
        sb.append("Content-Type:application/octet-stream\r\n\r\n");

        byte[] head = sb.toString().getBytes("utf-8");

        //获得输出流
        OutputStream out = new DataOutputStream(con.getOutputStream());
        //输出表头
        out.write(head);

        //文件正文部分
        //把文件已流文件的方式 推入到url中
        DataInputStream in = new DataInputStream(new FileInputStream(file));
        int bytes = 0;
        byte[] bufferOut = new byte[1024];
        while ((bytes = in.read(bufferOut)) != -1) {
            out.write(bufferOut, 0, bytes);
        }
        in.close();

        //结尾部分
        //定义最后数据分隔线
        byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");

        out.write(foot);

        out.flush();
        out.close();

        StringBuffer buffer = new StringBuffer();
        BufferedReader reader = null;
        String result = null;
        try {
            //定义BufferedReader输入流来读取URL的响应
            reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            if (result == null) {
                result = buffer.toString();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                reader.close();
            }
        }

        JSONObject jsonObj = JSONObject.parseObject(result);
        System.out.println(jsonObj);
        String typeName = "media_id";
        if(!"image".equals(type)){
            typeName = type + "_media_id";
        }
        LOGGER.info("jsonObj:{}",jsonObj);
        String mediaId = jsonObj.getString(typeName);
        return mediaId;
    }

}
